/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
<template>
  <div
    class="list-model"
    style="position: relative;"
  >
    <div class="table-box">
      <el-table
        class="fixed"
        :data="list"
        size="mini"
        style="width: 100%"
        @selection-change="_arrDelChange"
      >
        <el-table-column
          type="selection"
          width="50"
        ></el-table-column>
        <el-table-column
          prop="id"
          :label="$t('#')"
          width="50"
        ></el-table-column>
        <el-table-column
          :label="$t('Process Name')"
          min-width="200"
        >
          <template slot-scope="scope">
            <el-popover
              trigger="hover"
              placement="top"
            >
              <p>{{ scope.row.name }}</p>
              <div
                slot="reference"
                class="name-wrapper"
              >
                <router-link
                  :to="{ path: `/projects/${projectCode}/instance/list/${scope.row.id}` , query:{code: scope.row.processDefinitionCode}}"
                  tag="a"
                  class="links"
                ><span class="ellipsis">{{ scope.row.name }}</span></router-link>
              </div>
            </el-popover>
          </template>
        </el-table-column>
        <el-table-column
          :label="$t('State')"
          width="50"
        >
          <template slot-scope="scope">
            <span
              v-html="_rtState(scope.row.state)"
              style="cursor: pointer;"
            ></span>
          </template>
        </el-table-column>
        <el-table-column :label="$t('Run Type')">
          <template slot-scope="scope">
            {{_rtRunningType(scope.row.commandType)}}
          </template>
        </el-table-column>
        <!-- <el-table-column :label="$t('Scheduling Time')" width="135">
          <template slot-scope="scope">
            <span v-if="scope.row.scheduleTime">{{scope.row.scheduleTime | formatDate}}</span>
            <span v-else>-</span>
          </template>
        </el-table-column> -->
        <el-table-column
          :label="$t('Start Time')"
          width="135"
        >
          <template slot-scope="scope">
            <span>{{scope.row.startTime | formatDate}}</span>
          </template>
        </el-table-column>
        <el-table-column
          :label="$t('End Time')"
          width="135"
        >
          <template slot-scope="scope">
            <span>{{scope.row.endTime | formatDate}}</span>
          </template>
        </el-table-column>
        <el-table-column :label="$t('Duration')">
          <template slot-scope="scope">
            <span>{{scope.row.duration | filterNull}}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="runTimes"
          :label="$t('Run Times')"
        ></el-table-column>
        <el-table-column
          prop="recovery"
          :label="$t('fault-tolerant sign')"
        ></el-table-column>
        <el-table-column
          :label="$t('Dry-run flag')"
          width="100"
        >
          <template slot-scope="scope">
            <span v-if="scope.row.dryRun == 1">YES</span>
            <span v-else>NO</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="executorName"
          :label="$t('Executor')"
        ></el-table-column>
        <el-table-column
          prop="host"
          :label="$t('host')"
          min-width="210"
        ></el-table-column>

        <el-table-column
          :label="$t('Operation')"
          width="260"
          fixed="right"
        >
          <template slot-scope="scope">
            <div v-show="scope.row.disabled">
              <el-tooltip
                v-auth="['projects:instance:edit']"
                :content="$t('Edit')"
                placement="top"
                :enterable="false"
              >
                <span>
                  <el-button
                    type="primary"
                    size="mini"
                    icon="el-icon-edit-outline"
                    :disabled="scope.row.state !== 'SUCCESS' && scope.row.state !== 'PAUSE' && scope.row.state !== 'FAILURE' && scope.row.state !== 'STOP'"
                    @click="_reEdit(scope.row)"
                    circle
                  ></el-button>
                </span>
              </el-tooltip>
              <el-tooltip
                v-auth="['projects:instance:run']"
                :content="$t('Rerun')"
                placement="top"
                :enterable="false"
              >
                <span><el-button
                    type="primary"
                    size="mini"
                    :disabled="scope.row.state !== 'SUCCESS' && scope.row.state !== 'PAUSE' && scope.row.state !== 'FAILURE' && scope.row.state !== 'STOP'"
                    icon="el-icon-refresh"
                    @click="_reRun(scope.row,scope.$index)"
                    circle
                  ></el-button></span>
              </el-tooltip>
              <el-tooltip
                v-auth="['projects:instance:recover']"
                :content="$t('Recovery Failed')"
                placement="top"
                :enterable="false"
              >
                <span>
                  <el-button
                    type="success"
                    size="mini"
                    icon="el-icon-circle-close"
                    :disabled="scope.row.state !== 'FAILURE'"
                    @click="_restore(scope.row,scope.$index)"
                    circle
                  ></el-button>
                </span>
              </el-tooltip>
              <el-tooltip
                v-auth="['projects:instance:stop']"
                :content="scope.row.state === 'STOP' ? $t('Recovery Suspend') : $t('Stop')"
                placement="top"
                :enterable="false"
              >
                <span>
                  <!-- wait -->
                  <img
                    src="../../asset/wait.svg"
                    class="wait"
                    v-if="scope.row.state === 'READY_STOP'"
                  >
                  <el-button
                    v-else
                    type="danger"
                    size="mini"
                    :disabled="scope.row.state !== 'RUNNING_EXECUTION' && scope.row.state !== 'STOP'"
                    :icon="scope.row.state === 'STOP' ? 'el-icon-video-play' : 'el-icon-close'"
                    @click="_stop(scope.row,scope.$index)"
                    circle
                  ></el-button></span>

              </el-tooltip>

              <el-tooltip
                v-auth="['projects:instance:paused']"
                :content="scope.row.state === 'PAUSE' ? $t('Recovery Suspend') : $t('Pause')"
                placement="top"
                :enterable="false"
              >
                <span>
                  <img
                    src="../../asset/wait.svg"
                    class="wait"
                    v-if="scope.row.state === 'READY_PAUSE'"
                  >
                  <el-button
                    v-else
                    type="warning"
                    size="mini"
                    :icon="scope.row.state === 'PAUSE' ? 'el-icon-video-play' : 'el-icon-video-pause'"
                    :disabled="scope.row.state !== 'RUNNING_EXECUTION' && scope.row.state !== 'PAUSE'"
                    @click="_suspend(scope.row,scope.$index)"
                    circle
                  ></el-button></span>
              </el-tooltip>

              <el-tooltip
                v-auth="['projects:instance:delete']"
                :content="$t('Delete')"
                placement="top"
                :enterable="false"
              >
                <el-popconfirm
                  :confirmButtonText="$t('Confirm')"
                  :cancelButtonText="$t('Cancel')"
                  icon="el-icon-info"
                  iconColor="red"
                  :title="$t('Delete?')"
                  @onConfirm="_delete(scope.row,scope.row.id)"
                >
                  <el-button
                    type="danger"
                    size="mini"
                    icon="el-icon-delete"
                    :disabled="scope.row.state !== 'SUCCESS' && scope.row.state !== 'FAILURE' && scope.row.state !== 'STOP' && scope.row.state !== 'PAUSE'"
                    circle
                    slot="reference"
                  ></el-button>
                </el-popconfirm>
              </el-tooltip>
              <el-tooltip
                v-auth="['projects:instance:gantt']"
                :content="$t('Gantt')"
                placement="top"
                :enterable="false"
              >
                <span><el-button
                    type="primary"
                    size="mini"
                    icon="el-icon-s-operation"
                    @click="_gantt(scope.row)"
                    circle
                  ></el-button></span>
              </el-tooltip>
            </div>
            <div v-show="!scope.row.disabled">
              <!--Edit-->
              <el-button
                type="info"
                size="mini"
                icon="el-icon-edit-outline"
                disabled="true"
                circle
              >
              </el-button>

              <!--Rerun-->
              <span>
                <el-button
                  v-show="buttonType === 'run'"
                  type="info"
                  size="mini"
                  disabled="true"
                  circle
                >
                  <span style="padding: 0 2px">{{scope.row.count}}</span>
                </el-button>
              </span>
              <el-button
                v-show="buttonType !== 'run'"
                type="info"
                size="mini"
                icon="el-icon-refresh"
                disabled="true"
                circle
              >
              </el-button>

              <!--Store-->
              <span>
                <el-button
                  v-show="buttonType === 'store'"
                  type="success"
                  size="mini"
                  circle
                  disabled="true"
                >
                  <span style="padding: 0 3px">{{scope.row.count}}</span>
                </el-button>
              </span>
              <el-button
                v-show="buttonType !== 'store'"
                type="success"
                size="mini"
                circle
                icon="el-icon-circle-close"
                disabled="true"
              >
              </el-button>

              <!--Recovery Suspend/Pause-->
              <span>
                <el-button
                  v-show="(scope.row.state === 'PAUSE' || scope.row.state === 'STOP') && buttonType === 'suspend'"
                  type="warning"
                  size="mini"
                  circle
                  disabled="true"
                >
                  <span style="padding: 0 3px">{{scope.row.count}}</span>
                </el-button>
              </span>

              <!--Recovery Suspend-->
              <el-button
                v-show="(scope.row.state === 'PAUSE' || scope.row.state === 'STOP') && buttonType !== 'suspend'"
                type="warning"
                size="mini"
                circle
                icon="el-icon-video-play"
                disabled="true"
              >
              </el-button>

              <!--Pause-->
              <span>
                <el-button
                  v-show="scope.row.state !== 'PAUSE'"
                  type="warning"
                  size="mini"
                  circle
                  icon="el-icon-close"
                  disabled="true"
                >
                </el-button>
              </span>

              <!--Stop-->
              <span>
                <el-button
                  v-show="scope.row.state !== 'STOP'"
                  type="warning"
                  size="mini"
                  circle
                  icon="el-icon-video-pause"
                  disabled="true"
                >
                </el-button>
              </span>

              <!--Delete-->
              <el-button
                type="danger"
                circle
                size="mini"
                icon="el-icon-delete"
                :disabled="true"
              >
              </el-button>

              <!--Gantt-->
              <el-button
                type="success"
                circle
                size="mini"
                icon="el-icon-s-operation"
                disabled="true"
              >
              </el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-tooltip
      :content="$t('Delete')"
      placement="top"
      :enterable="false"
    >
      <el-popconfirm
        :confirmButtonText="$t('Confirm')"
        :cancelButtonText="$t('Cancel')"
        :title="$t('Delete?')"
        @onConfirm="_delete({},-1)"
      >
        <el-button
          style="position: absolute; bottom: -48px; left: 19px;"
          type="primary"
          size="mini"
          :disabled="!strDelete"
          slot="reference"
        >{{$t('Delete')}}</el-button>
      </el-popconfirm>
    </el-tooltip>
  </div>
</template>
<script>
  import _ from 'lodash'
  import { mapActions, mapState } from 'vuex'
  import { tasksState, runningType } from '@/conf/home/pages/dag/_source/config'

  export default {
    name: 'list',
    data () {
      return {
        // data
        list: [],
        /* 用于延迟提示,缓存列表行数据 */
        cRow: null,
        timer: null,
        // btn type
        buttonType: '',
        strDelete: '',
        checkAll: false
      }
    },
    props: {
      processInstanceList: Array,
      pageNo: Number,
      pageSize: Number
    },
    methods: {
      ...mapActions('dag', ['editExecutorsState', 'deleteInstance', 'batchDeleteInstance']),
      /**
       * Return run type
       */
      _rtRunningType (code) {
        return _.filter(runningType, v => v.code === code)[0].desc
      },
      /**
       * Return status
       */
      _rtState (code) {
        let o = tasksState[code]
        return `<em class="fa ansfont ${o.icoUnicode} ${o.isSpin ? 'as as-spin' : ''}" style="color:${o.color}" data-toggle="tooltip" data-container="body" title="${o.desc}"></em>`
      },
      /**
       * delete
       */
      _delete (item, i) {
        // remove tow++
        if (i < 0) {
          this._batchDelete()
          return
        }
        // remove one
        this.deleteInstance({
          processInstanceId: item.id
        }).then(res => {
          this._onUpdate()
          this.$message.success(res.msg)
        }).catch(e => {
          this.$message.error(e.msg || '')
        })
      },
      /**
       * edit
       */
      _reEdit (item) {
        this.$router.push({ path: `/projects/${this.projectCode}/instance/list/${item.id}`, query: { code: item.processDefinitionCode } })
      },
      /**
       * Rerun
       * @param REPEAT_RUNNING
       */
      _reRun (item, index) {
        this._countDownFn({
          id: item.id,
          executeType: 'REPEAT_RUNNING',
          index: index,
          buttonType: 'run'
        })
      },
      /**
       * Resume running
       * @param PAUSE => RECOVER_SUSPENDED_PROCESS
       * @param FAILURE => START_FAILURE_TASK_PROCESS
       */
      _restore (item, index) {
        this._countDownFn({
          id: item.id,
          executeType: 'START_FAILURE_TASK_PROCESS',
          index: index,
          buttonType: 'store'
        })
      },
      /**
       * stop
       * @param STOP
       */
      _stop (item, index) {
        if (item.state === 'STOP') {
          this._countDownFn({
            id: item.id,
            executeType: 'RECOVER_SUSPENDED_PROCESS',
            index: index,
            buttonType: 'suspend'
          })
        } else {
          /* 暂停 */
          this._upExecutorsState({
            processInstanceId: item.id,
            executeType: 'STOP'
          })
        }
      },
      /**
       * pause
       * @param PAUSE
       */
      _suspend (item, index) {
        if (item.state === 'PAUSE') {
          this._countDownFn({
            id: item.id,
            executeType: 'RECOVER_SUSPENDED_PROCESS',
            index: index,
            buttonType: 'suspend'
          })
        } else {
          this._upExecutorsState({
            processInstanceId: item.id,
            index,
            executeType: 'PAUSE'
          })
        }
      },
      /**
       * operating
       */
      _upExecutorsState (o) {
        const { executeType, index } = o
        this.editExecutorsState(o).then(res => {
          // 在子节点运行显示loading, 完成后提示
          // eslint-disable-next-line
          if (executeType === 'PAUSE' || 'STOP') {
            this.list[index] && (this.list[index].isWait = true)
            this.cRow = Object.assign({}, { ...o, isWait: true })
            this.$nextTick(() => {
              clearInterval(this.timer)
              this.timer = setInterval(() => {
                if (!(this.cRow && this.cRow.processInstanceId)) clearInterval(this.timer)
                this.list.forEach((v) => {
                  if (this.cRow && (v.id === this.cRow.processInstanceId) && (v.state === 'STOP' || v.state === 'PAUSE')) {
                    this.$message.success('操作成功')
                    this.cRow = null
                    clearInterval(this.timer)
                  }
                })
              }, 1000)
            })
          }
          // this.$message.success(res.msg)
          $('body').find('.tooltip.fade.top.in').remove()
          this._onUpdate()
        }).catch(e => {
          this.$message.error(e.msg || '')
          this._onUpdate()
        })
      },
      /**
       * Countdown method refresh
       */
      _countDownFn (param) {
        this.buttonType = param.buttonType
        this.editExecutorsState({
          processInstanceId: param.id,
          executeType: param.executeType
        }).then(res => {
          this.list[param.index].disabled = false
          $('body').find('.tooltip.fade.top.in').remove()
          this.$forceUpdate()
          this.$message.success(res.msg)
          // Countdown
          this._countDown(() => {
            this._onUpdate()
          }, param.index)
        }).catch(e => {
          this.$message.error(e.msg || '')
          this._onUpdate()
        })
      },
      /**
       * update
       */
      _onUpdate () {
        this.$emit('on-update')
      },
      /**
       * list data handle
       */
      _listDataHandle (data) {
        if (data.length) {
          _.map(data, v => {
            v.disabled = true
            v.isWait = false
            v.count = 9
          })
        }
        return data
      },
      /**
       * Countdown
       */
      _countDown (fn, index) {
        const TIME_COUNT = 10
        let timer
        let $count
        if (!timer) {
          $count = TIME_COUNT
          timer = setInterval(() => {
            if ($count > 0 && $count <= TIME_COUNT) {
              $count--
              this.list[index].count = $count
              this.$forceUpdate()
            } else {
              fn()
              clearInterval(timer)
              timer = null
            }
          }, 1000)
        }
      },
      _gantt (item) {
        this.$router.push({ path: `/projects/${this.projectCode}/instance/gantt/${item.id}` })
      },
      _topCheckBoxClick (v) {
        this.list.forEach((item, i) => {
          this.$set(this.list[i], 'isCheck', v)
        })
        this._arrDelChange()
      },
      _arrDelChange (v) {
        let arr = []
        arr = _.map(v, 'id')
        this.strDelete = _.join(arr, ',')
      },
      _batchDelete () {
        this.batchDeleteInstance({
          processInstanceIds: this.strDelete
        }).then(res => {
          this._onUpdate()
          this.checkAll = false
          this.strDelete = ''
          this.$message.success(res.msg)
        }).catch(e => {
          this._onUpdate()
          this.checkAll = false
          this.strDelete = ''
          this.$message.error(e.msg || '')
        })
      }
    },
    watch: {
      processInstanceList: {
        handler (a) {
          this.checkAll = false
          this.list = []
          setTimeout(() => {
            this.list = _.cloneDeep(this._listDataHandle(a))
          })
        },
        immediate: true,
        deep: true
      },
      pageNo () {
        this.strDelete = ''
      }
    },
    created () {
    },
    mounted () {
    },
    destroyed () {
      clearInterval(this.timer)
    },
    computed: {
      ...mapState('dag', ['projectCode'])
    },
    components: {}
  }
</script>
<style lang="scss" scoped>
.wait {
  display: inline-block;
  -webkit-animation: rotation 10s linear infinite;
  animation: rotation 3s linear infinite;
}
@keyframes rotation {
  0% {
    -webkit-transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
  }
}
</style>
